import os
import json
import pandas as pd
from gensim import models, corpora
from typing import Dict, Tuple, List
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer

key_words = {}

if os.path.exists('./key_words.json'):
    with open('./key_words.json', 'r', encoding='utf-8') as f:
        key_words = json.load(f)


def GetWordsDict(cleaned_corpus: List[str]) -> Tuple[Dict[str, int], ]:
    """
    @param
        cleaned_corpus: cleaned title and content of a text file
    @function
        calculate words and remove stop words
    @return
        dict of word and its number of show-ups in text
    """
    count_vec = CountVectorizer(token_pattern=r'\w+', min_df=0)
    tfidf_vec = TfidfTransformer()
    count_val = count_vec.fit_transform(cleaned_corpus)
    tfidf_val = tfidf_vec.fit_transform(count_val).toarray()
    count_val = count_val.toarray()

    voc = count_vec.vocabulary_
    voc = dict(sorted(voc.items(), key=lambda x: x[1]))

    words_dict = {
        word:{'count':list(count_val[:,voc[word]]), 'tfidf':list(tfidf_val[:,voc[word]])} 
        for word in voc
    }

    return words_dict


def LDAModeling(cleaned_corpus: list, num_topics: int, word_separator: str = ' '):
    words = [text.split(word_separator) for text in cleaned_corpus]
    words = [[i for i in l if i != ''] for l in words]

    dct = corpora.Dictionary(words)
    corpus = [dct.doc2bow(wds) for wds in words]
    lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dct, num_topics=num_topics, random_state=2022)

    return lda, corpus, dct


def AssocRuleModeling(corpus: list, keywords: list, word_separator: str = ' ') -> list:
    key_words_set = set(keywords)
    data = [i.split(word_separator) for i in corpus]
    data = [list(set(i) & key_words_set) for i in data]
    return [i for i in data if i != []]


def DFTextGroupBy(df: pd.DataFrame, by, text_col: str) -> Dict:
    dict_groupby = dict(tuple(df.groupby(by)))
    return {item[0]: list(item[1][text_col]) for item in dict_groupby.items()}


# def BilibiliAnalyze() -> List:
#     df = pd.read_csv(r'./input_data/Bilibili/jingju_comment.csv')
#     # for i in range(len(df)):
#     #     df.iloc[i, 5] = datetime.strptime(df.iloc[i, 5], '%d/%m/%Y %H:%M:%S')
#     # df = df.sort_values(by='ctime', ascending=False)
#     df_sex = df[['sex', 'uname', 'message']]
#     dict_sex = dict(tuple(df_sex.groupby(['sex', 'uname'])))
#     for item in dict_sex.items():
#         dict_sex[item[0]] = ' '.join(list(item[1]['message']))

#     df_oid = df[['oid', 'message']]
#     dict_oid = dict(tuple(df_oid.groupby('oid')))
#     for item in dict_oid.items():
#         dict_oid[item[0]] = ' '.join(list(item[1]['message']))

#     df_male = df[df['sex']=='男']
#     df_female = df[df['sex']=='女']

#     video_visit_freq_male = df_male[['uname', 'oid']].groupby(['uname'])['oid'].nunique().to_dict()
#     video_visit_freq_female = df_female[['uname', 'oid']].groupby(['uname'])['oid'].nunique().to_dict()

#     comment_cnt_male = df_male[['uname', 'message']].groupby(['uname']).transform('count')
#     comment_freq_male = dict(zip(df_male['uname'], comment_cnt_male))
#     comment_cnt_female = df_female[['uname', 'message']].groupby(['uname']).transform('count')
#     comment_freq_female = dict(zip(df_female['uname'], comment_cnt_female))

#     return dict_sex, dict_oid, video_visit_freq_male, video_visit_freq_female, comment_freq_male, comment_freq_female


# class WordDescription(object):
#     """
#      Description of a word, containing tag(type of word, like 'n':noun, etc.)
#      and count
#     """

#     def __init__(self, tag: str, count: int) -> None:
#         self.tag = tag
#         self.count = count

#     def set(self, tag: str, count: int) -> None:
#         self.tag = tag
#         self.count = count

#     def __lt__(self, other: object) -> bool:
#         return self.count < other.count

#     def __gt__(self, other: object) -> bool:
#         return self.count > other.count

#     def __eq__(self, other: object) -> bool:
#         return self.count == other.count and self.tag == other.tag

#     def __str__(self) -> str:
#         return 'tag: %s, count: %d' % (self.tag, self.count)

#     def __repr__(self) -> str:
#         return 'tag: %s, count: %d' % (self.tag, self.count)
